/*
 *  Class name: TeamDetailDialogWindow.java
 *  Version: 1.0
 *  Date: 12.12.2013
 */
package cz.muni.fi.pa165.soccergamesarchive.restclient.gui.dialogs;

import cz.muni.fi.pa165.soccergamesarchive.businesslayer.dtos.PlayerDTO;
import cz.muni.fi.pa165.soccergamesarchive.businesslayer.dtos.TeamDTO;
import cz.muni.fi.pa165.soccergamesarchive.restclient.gui.SGAClientMainFrame;
import cz.muni.fi.pa165.soccergamesarchive.restclient.gui.components.enums.Operation;
import cz.muni.fi.pa165.soccergamesarchive.restclient.gui.components.interfaces.ResultListenable;
import cz.muni.fi.pa165.soccergamesarchive.restclient.gui.components.pageablelist.PageableListPanel;
import cz.muni.fi.pa165.soccergamesarchive.restclient.gui.components.pageablelist.entity.EditablePlayerList;
import cz.muni.fi.pa165.soccergamesarchive.restclient.gui.components.pageablelist.items.PageableListItemButton;
import cz.muni.fi.pa165.soccergamesarchive.restclient.utils.JOptionDialogWindowHandler;
import cz.muni.fi.pa165.soccergamesarchive.restclient.utils.StringUtils;
import java.awt.Dimension;
import javax.swing.ImageIcon;

/**
 *
 * @author Michal Ďuriš
 */
public class TeamDetailDialogWindow extends javax.swing.JDialog implements
        ResultListenable {

    private static final long serialVersionUID = 1L;

    private Operation state = Operation.NO_OP;

    private PageableListPanel<PlayerDTO> playerList;

    private final PageableListItemButton<TeamDTO> team;

    /**
     * Creates new form TeamDetailDialogWindow
     *
     * @param team
     * @param modalityType
     */
    public TeamDetailDialogWindow(PageableListItemButton<TeamDTO> team,
                                  ModalityType modalityType) {
        super(team.getParentList().getOwner(), modalityType);

        this.team = team;

        initComponents();

        setLocationRelativeTo(getOwner());
    }

    public TeamDetailDialogWindow init() {

        identifyState();
        updateDialogWindowToCurrentState();

        return this;
    }

    private void identifyState() {
        if (team.getEntity().getId() == null) {
            state = Operation.ADD;
        } else {
            state = Operation.CHANGE;
        }
    }

    private void updateDialogWindowToCurrentState() {

        switch (state) {
            case ADD:
                setTitle("Add team");
                break;
            case CHANGE:
                setTitle("Change team");
                updateTeamComponents();
                addPlayerListComponent();
                actionButton.setText("Change");
                break;
            default:
                JOptionDialogWindowHandler.showInfoDialogWindow(this, "Error",
                        "Unable to recognize operation. Closing the dialog. Sorry...");
                dispose();
        }
    }

    private void updateTeamComponents() {
        nameTextField.setText(team.getEntity().getName());
        managerNameTextField.setText(team.getEntity().getManagerName());
    }

    private void addPlayerListComponent() {

        playerList = new EditablePlayerList(this, "Players", team);
        playerList.init(team.getEntity().getPlayers());

        playerList.setPreferredSize(new java.awt.Dimension(120, 200));

        getContentPane().add(playerList, java.awt.BorderLayout.CENTER);
        pack();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        teamPanel = new javax.swing.JPanel();
        nameLabel = new javax.swing.JLabel();
        managerNameLabel = new javax.swing.JLabel();
        nameTextField = new javax.swing.JTextField();
        managerNameTextField = new javax.swing.JTextField();
        errorLabel = new javax.swing.JLabel();
        buttonsPanel = new javax.swing.JPanel();
        actionButton = new javax.swing.JButton();
        cancelButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Team");
        setIconImage(new ImageIcon(getClass().getResource("/icons/soccer-icon.png")).getImage());

        teamPanel.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Team", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Arial", 1, 14), new java.awt.Color(0, 102, 255))); // NOI18N

        nameLabel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
        nameLabel.setText("Name:");

        managerNameLabel.setFont(new java.awt.Font("Arial", 0, 12)); // NOI18N
        managerNameLabel.setText("Manager name:");

        nameTextField.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N

        managerNameTextField.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N

        errorLabel.setFont(new java.awt.Font("Arial", 1, 12)); // NOI18N
        errorLabel.setForeground(new java.awt.Color(255, 0, 0));
        errorLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);

        javax.swing.GroupLayout teamPanelLayout = new javax.swing.GroupLayout(teamPanel);
        teamPanel.setLayout(teamPanelLayout);
        teamPanelLayout.setHorizontalGroup(
            teamPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(teamPanelLayout.createSequentialGroup()
                .addGroup(teamPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(managerNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(teamPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(nameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 148, Short.MAX_VALUE)
                    .addComponent(managerNameTextField)))
            .addGroup(teamPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(errorLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        teamPanelLayout.setVerticalGroup(
            teamPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(teamPanelLayout.createSequentialGroup()
                .addGroup(teamPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(nameLabel)
                    .addComponent(nameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(teamPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(managerNameLabel)
                    .addComponent(managerNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(errorLabel))
        );

        getContentPane().add(teamPanel, java.awt.BorderLayout.PAGE_START);

        buttonsPanel.setPreferredSize(new java.awt.Dimension(250, 45));

        actionButton.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N
        actionButton.setText("Add");
        actionButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                actionButtonActionPerformed(evt);
            }
        });

        cancelButton.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N
        cancelButton.setText("Cancel");
        cancelButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                cancelButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout buttonsPanelLayout = new javax.swing.GroupLayout(buttonsPanel);
        buttonsPanel.setLayout(buttonsPanelLayout);
        buttonsPanelLayout.setHorizontalGroup(
            buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, buttonsPanelLayout.createSequentialGroup()
                .addContainerGap(92, Short.MAX_VALUE)
                .addComponent(actionButton)
                .addGap(18, 18, 18)
                .addComponent(cancelButton)
                .addContainerGap())
        );

        buttonsPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {actionButton, cancelButton});

        buttonsPanelLayout.setVerticalGroup(
            buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, buttonsPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(cancelButton)
                    .addComponent(actionButton))
                .addContainerGap())
        );

        buttonsPanelLayout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {actionButton, cancelButton});

        getContentPane().add(buttonsPanel, java.awt.BorderLayout.PAGE_END);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void actionButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_actionButtonActionPerformed
        handleActionButton();
    }//GEN-LAST:event_actionButtonActionPerformed

    private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
        dispose();
    }//GEN-LAST:event_cancelButtonActionPerformed

    @Override
    public void processSuccessResult() {
        JOptionDialogWindowHandler.showInfoDialogWindow(this, "Info",
                "Team was saved.");

        if (state == Operation.ADD) {

            state = Operation.CHANGE;
            updateDialogWindowToCurrentState();
        }
    }

    @Override
    public void processFailResult() {
        JOptionDialogWindowHandler.showErrorDialogWindow(this, "Error",
                "Unable to save the team! Try again later.");
    }

    private void handleActionButton() {
        switch (state) {
            case ADD:
                handleAddAction();
                break;
            case CHANGE:
                handleChangeAction();
                break;
            default:
                JOptionDialogWindowHandler.showInfoDialogWindow(this, "Error",
                        "Unable to recognize operation. Operation aborted. Closing the dialog. Sorry...");
                dispose();
        }
    }

    private void handleAddAction() {

        if (validateUserInput()) {

            updateEntity(team);
            team.store(this);
        }
    }

    private void handleChangeAction() {

        if (validateUserInput()) {

            PageableListItemButton<TeamDTO> newTeam = team.getParentList()
                    .createEntityListItem();
            newTeam.getEntity().setId(team.getEntity().getId());
            updateEntity(newTeam);

            team.change(newTeam, this);
        }
    }

    private boolean validateUserInput() {

        StringBuilder errorMessage = new StringBuilder("<html> ");
        boolean errorFlag = false;

        delegateNormalStateToComponents();

        if (StringUtils.isBlank(nameTextField.getText())) {

            errorFlag = true;

            nameLabel.setForeground(SGAClientMainFrame.ERROR_STATE_COLOR);
            errorMessage.append("Name cannot be empty !!! <br> ");
        }

        if (StringUtils.isBlank(managerNameTextField.getText())) {

            errorFlag = true;

            managerNameLabel.setForeground(SGAClientMainFrame.ERROR_STATE_COLOR);
            errorMessage.append("Manager name cannot be empty !!!");
        }

        if (errorFlag) {
            errorLabel.setText(errorMessage.toString());
            updateWindow();
        }

        return !errorFlag;
    }

    private void delegateNormalStateToComponents() {

        errorLabel.setText("");

        nameLabel.setForeground(SGAClientMainFrame.NORMAL_STATE_COLOR);
        managerNameLabel.setForeground(SGAClientMainFrame.NORMAL_STATE_COLOR);

        updateWindow();
    }

    private void updateEntity(PageableListItemButton<TeamDTO> entity) {

        entity.getEntity().setName(nameTextField.getText());
        entity.getEntity().setManagerName(managerNameTextField.getText());

        entity.getEntity().setPlayers(team.getEntity().getPlayers());
    }

    private void updateWindow() {

        Dimension actualSize = getSize();

        pack();

        if (!actualSize.equals(getPreferredSize())) {
            setPreferredSize(getSize());
        }
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton actionButton;
    private javax.swing.JPanel buttonsPanel;
    private javax.swing.JButton cancelButton;
    private javax.swing.JLabel errorLabel;
    private javax.swing.JLabel managerNameLabel;
    private javax.swing.JTextField managerNameTextField;
    private javax.swing.JLabel nameLabel;
    private javax.swing.JTextField nameTextField;
    private javax.swing.JPanel teamPanel;
    // End of variables declaration//GEN-END:variables

}
